import whiteList from "./whiteList";
import BASE_URL from "../baseUrl";
import language from "../lang/index";
import errCode from "../lang/indexCode";
import { getCurrentInstance } from "vue";
// 1. 定义核心类型
interface RequestConfig {
	header?: Record<string, string>;
	timeout?: number;
	[key: string]: any;
}

interface ApiResponse<T = any> {
	code: number;
	data: T;
	msg?: string;
	trace_id?: string;
}
interface RequestOptions {
	url: string;
	params?: Record<string, any>;
	method?: "GET" | "POST" | "PUT" | "DELETE";
	config?: RequestConfig;
	showLoading?: boolean;
}

// 2. 主请求函数
export const requestFunction = <T = any>(
	url: string,
	params?: Record<string, any>,
	method: "GET" | "POST" | "PUT" | "DELETE" = "GET",
	config?: RequestOptions["config"],
	showLoading?: false
): Promise<T> => {
	const UNI_LOCALE = uni.getLocale();
	const instance: any = getCurrentInstance();
	// 显示加载状态
	if (showLoading) {
		uni.showLoading({
			title: language[UNI_LOCALE]["request.loading"],
			mask: true,
		});
	}
	// 处理URL
	const requestUrl = url.indexOf("http") !== -1 ? url : BASE_URL + url;
	// 构建请求配置
	const requestConfig: RequestConfig & {
		url: string;
		data: any;
		method: string;
	} = {
		url: requestUrl,
		data: params,
		method,
		timeout: 30000,
		...config,
	};
	const traceId = useUniversalStorage("trace_id", "");
	// 处理Token
	const token = useUniversalStorage("token", "");

	if (token.value && token.value != "null") {
		requestConfig.header = {
			Authorization: token.value,
		};
	} else if (whiteList.indexOf(url) === -1) {
		// 非白名单且无Token
		loginLoading(language[UNI_LOCALE]["request.noLogin"]);
		return Promise.reject(new Error("未登录"));
	}

	return new Promise((resolve, reject) => {
		uni.request({
			...requestConfig,
			success: (res: { data: ApiResponse<T> }) => {
				if (showLoading) {
					uni.hideLoading();
				}

				// 存储trace_id
				if (res.data.code !== 0 && res.data.trace_id) {
					traceId.value = res.data.trace_id;
				}

				// 处理登录过期
				if (res.data.code === 11005 || res.data.code === 11006) {
					loginLoading(language[UNI_LOCALE]["request.noLoginToken"]);
					reject(new Error("登录已过期"));
					return;
				}

				// 处理错误码
				if (res.data.code !== 0) {
					handleErrorResponse(res.data, UNI_LOCALE);
					reject(res.data);
					return;
				}

				// 成功响应
				resolve(res);
			},
			fail: (err: any) => {
				// 存储trace_id
				if (err.data?.trace_id) {
					uni.setStorageSync("trace_id", err.data.trace_id);
					traceId.value = err.data.trace_id;
				}

				// 显示错误消息
				if (err.errMsg) {
					instance?.proxy.$message(err.errMsg, "warning");
				}

				// 处理401错误
				if (err.code === "401") {
					loginLoading(language[UNI_LOCALE]["request.noLoginToken"]);
					reject(new Error("登录已过期"));
				} else {
					if (showLoading) {
						uni.hideLoading();
					}
					reject(err);
				}
			},
		});
	});
};

// 3. 错误处理函数
const handleErrorResponse = (response: ApiResponse, locale: string) => {
	let message = response.msg || "";

	// 特殊处理10004和10005错误码
	if (response.code === 10004 || response.code === 10005) {
		message = message
			.replace("车端执行命令失败", "")
			.replace("车端执行命令超时", "");
		message = errCode[locale][String(response.code)] + message;
	} else if (errCode[locale][String(response.code)]) {
		message = errCode[locale][String(response.code)];
	}

	// 显示错误提示
	uni.showToast({
		title: message,
		icon: "none",
		duration: 2000,
	});
};

// 4. 登录跳转函数
const loginLoading = (title: string) => {
	const duration = 2000;
	const pages = getCurrentPages();
	const currentPage = pages[pages.length - 1];

	if (!currentPage.route.includes("pages/login/index")) {
		uni.showToast({
			title,
			icon: "none",
			duration,
			complete: () => {
				setTimeout(() => {
					uni.reLaunch({
						url: "/pages/login/index",
					});
					uni.hideToast();
				}, duration);
			},
		});
	}
};

export default requestFunction;
